package cn.cumulomq.utils;

import java.util.ArrayList;
import java.util.Date;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import cn.ait.umc.endpoint.Endpoint;
import cn.ait.umc.message.AFTNAddress;
import cn.ait.umc.message.AFTNMessage;
import cn.ait.umc.message.Message;
import cn.ait.umc.message.SITAAddress;
import cn.ait.umc.message.SITAMessage;
import cn.cumulomq.entity.MessageCategory;
import cn.cumulomq.entity.TeleMessage;
import cn.cumulomq.service.MessageCategoryService;

public class MessageUtil implements MessageConstants{
	private static Map<String,String> msgCategoryRule = new IdentityHashMap<String,String>();
	static{
		String parseTypes = PropertiesUtil.getProperty("message.parseTypes");
		if(parseTypes!=null){
			String[] types = parseTypes.trim().split("\\|");
			for(String type:types){
				msgCategoryRule.put(type, PropertiesUtil.getProperty("message.categoryRegx."+type));
			}
		}
	}
	/**
	 * 将UMC消息转换为存储的 TeleMessage
	 * @param umcMsg
	 * @return
	 */
    public static TeleMessage createTeleFromUmc(Message umcMsg) {
        Date now = new Date();
        TeleMessage msg = new TeleMessage();
        if (umcMsg.getSentDate() != null) {
            msg.setMsgDirection(MSG_DIRECTION_SEND);
            msg.setSentDate(umcMsg.getSentDate());
            umcMsg.setReceivedDate(umcMsg.getSentDate());
        } else {
            msg.setMsgDirection(MSG_DIRECTION_RECEIVE);
            msg.setReceivedDate(umcMsg.getReceivedDate());
        }
        msg.setCreateTime(now);
        msg.setCid(umcMsg.getCid());
        msg.setCsn(umcMsg.getCsn());
        msg.setAdditionalService(umcMsg.getAdditionalService());
        msg.setOriginalText(umcMsg.getOriginalText());
        if (umcMsg instanceof AFTNMessage) {
            msg.setText(((AFTNMessage) umcMsg).getText());
            msg.setFilingTime(((AFTNMessage) umcMsg).getFilingTime());
            msg.setPriorityAlarm(((AFTNMessage) umcMsg).getPriorityAlarm());

            StringBuffer sb = new StringBuffer();
            AFTNAddress[] addresses = ((AFTNMessage) umcMsg).getAddressees();
            if (addresses != null) {
                for (AFTNAddress address : addresses) {
                    if (address != null)
                        sb.append(address.getAddress()).append(' ');
                }

                msg.setAddressees(sb.toString().trim());
            }
            msg.setOptionalHeading(((AFTNMessage) umcMsg)
                    .getOptionalHeading());
            msg.setOriginator(((AFTNMessage) umcMsg).getOriginator()
                    .getAddress());
            msg.setPriorityIndicator(((AFTNMessage) umcMsg)
                    .getPriorityIndicator().name());
            msg.setMsgType(MSG_TYPE_AFTN);
        } else if (umcMsg instanceof SITAMessage) {
            msg.setText(((SITAMessage) umcMsg).getText());

            StringBuffer sb = new StringBuffer();
            SITAAddress[] addresses = ((SITAMessage) umcMsg).getNormalAddress();
            if (addresses != null) {
                for (SITAAddress address : addresses) {
                    if (address != null)
                        sb.append(address.getAddress()).append(' ');
                }
                msg.setAddressees(sb.toString().trim());
            }
            msg.setMessageIdentity(((SITAMessage) umcMsg)
                    .getMessageIdentity());
            msg.setOriginator(((SITAMessage) umcMsg).getOriginator()
                    .getAddress());
            msg.setFilingTime(((SITAMessage) umcMsg).getFilingTime());
            msg.setPriorityIndicator(((SITAMessage) umcMsg).getPriority()
                    .name());
            msg.setDoubleSignature(((SITAMessage) umcMsg)
                    .getDoubleSignature());
            msg.setMsgType(MSG_TYPE_SITA);
        } else {
            msg.setParseError(umcMsg.getParseError());
            msg.setMsgType(MSG_TYPE_UNKNOWN);
        }

        msg.setMsgCategory(findMsgCategory(msg.getText()));
        return msg;
    }

    public static List<AFTNMessage> splitAftn(AFTNMessage msgAFTN)
            throws Exception {
        AFTNAddress[] addresses = msgAFTN.getAddressees();
        int len = addresses.length;
        List<AFTNMessage> list = new ArrayList<AFTNMessage>();
        if (len > AFTN_ADDRESS_LEN) {
            for (int i = 0; (i * AFTN_ADDRESS_LEN) < len; i++) {
                AFTNAddress tempAddress[];
                if ((i + 1) * AFTN_ADDRESS_LEN < len) {
                    tempAddress = new AFTNAddress[AFTN_ADDRESS_LEN];
                    for (int j = 0; j < AFTN_ADDRESS_LEN; j++) {
                        tempAddress[j] = addresses[(i * AFTN_ADDRESS_LEN) + j];
                    }
                } else {
                    tempAddress = new AFTNAddress[len - (i * AFTN_ADDRESS_LEN)];
                    for (int j = 0; j < (len - i * AFTN_ADDRESS_LEN); j++) {
                        tempAddress[j] = addresses[(i * AFTN_ADDRESS_LEN) + j];
                    }
                }
                msgAFTN.setAddressees(tempAddress);
                splitAFTNText(list, msgAFTN);
            }
        } else {
            splitAFTNText(list, msgAFTN);
        }
        return list;
    }

    
    private static void splitAFTNText(List<AFTNMessage> list, AFTNMessage msg)
            throws Exception {
        String text = msg.getText();
        double size = text.getBytes().length;
        if (size > AFTN_TEXT_LEN) {
            int partTotal = (int) Math.ceil(size / AFTN_TEXT_ACTUAL_LEN);
            int partNum = 0;
            while (text != null && partNum <= partTotal) {
                String tempText;
                partNum++;
                if (partNum != partTotal) {
                    int k = getCharlen(text, AFTN_TEXT_ACTUAL_LEN);
                    tempText = text.substring(0, k) + "\r\n// END PART "
                            + partNum + " //";
                    text = text.substring(k);
                } else {
                    tempText = text + "\r\n// END PART " + partNum + "/ "
                            + partTotal + " //";
                    text = null;
                }
                AFTNMessage msgAFTN = (AFTNMessage) msg.clone();
                msgAFTN.setText(tempText);
                list.add(msgAFTN);
            }
        } else {
            AFTNMessage msgAFTN = (AFTNMessage) msg.clone();
            list.add(msgAFTN);
        }
    }
    
    private static int getCharlen(String text, int textByteLen) {
        for (int i = 0; i < textByteLen; i++) {
            
            String temp = text.substring(i, i + 1);
            if (temp.getBytes().length > 1) {
                textByteLen = textByteLen - temp.getBytes().length + 1;

            }
        }
        return textByteLen;
    }

    public static void replaceHeadAndEnd(Endpoint endpoint){
    	if(endpoint.getLc().getConfig().getAftnProtocolParam().getStartOfMsgChars().contains(STRING_SOH)){
    		endpoint.getLc().getConfig().getAftnProtocolParam().setStartOfMsgChars(TO_SOH);
    	}
    	if(endpoint.getLc().getConfig().getAftnProtocolParam().getEndOfMsgChars().contains(STRING_ETX)){
    		endpoint.getLc().getConfig().getAftnProtocolParam().setEndOfMsgChars(TO_ETX);
    	}
    }
    public static String findMsgCategory(String msg){
    	String category="OTHER";
    	for(Entry<String, String> cr :msgCategoryRule.entrySet()){
    		if(msg.matches(cr.getValue()))return cr.getKey();
    	}
    	return category;
    }
    
}
